home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 7
/
Aminet 7 - August 1995.iso
/
Aminet
/
comm
/
net
/
rhslip38_9_030.lha
/
rhslip
/
src
/
cslip.h
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-26
|
11KB
|
326 lines
/* $Id: cslip.h,v 1.1 1993/08/17 00:00:00 rhialto Exp $
*
* The code in this file is derived from and very similar to the example
* implementation provided in RFC 1144, and is therefore sort-of covered
* by its copyright:
*
* Copyright (C) 1989 Regents of the University of California.
*
* modified for KA9Q Internet Software Package by
* Katie Stevens (dkstevens@ucdavis.edu)
* University of California, Davis
* Computing Services
* - 01-31-90 initial adaptation
*
* - Feb 1991 Bill_Simpson@um.cc.umich.edu
* variable number of conversation slots
* allow zero or one slots
* separate routines
* status display
*
* This adaptation (for rhcslip.device) by Olaf 'Rhialto' Seibert.
*/
/*
* Compressed packet format:
*
* The first octet contains the packet type (top 3 bits), TCP
* 'push' bit, and flags that indicate which of the 4 TCP sequence
* numbers have changed (bottom 5 bits). The next octet is a
* conversation number that associates a saved IP/TCP header with
* the compressed packet. The next two octets are the TCP checksum
* from the original datagram. The next 0 to 15 octets are
* sequence number changes, one change per bit set in the header
* (there may be no changes and there are two special cases where
* the receiver implicitly knows what changed -- see below).
*
* There are 5 numbers which can change (they are always inserted
* in the following order): TCP urgent pointer, window,
* acknowlegement, sequence number and IP ID. (The urgent pointer
* is different from the others in that its value is sent, not the
* change in value.) Since typical use of SLIP links is biased
* toward small packets (see comments on MTU/MSS below), changes
* use a variable length coding with one octet for numbers in the
* range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
* range 256 - 65535 or 0. (If the change in sequence number or
* ack is more than 65535, an uncompressed packet is sent.)
*/
/*
* Packet types (must not conflict with IP protocol version)
*
* The top nibble of the first octet is the packet type. There are
* three possible types: IP (not proto TCP or tcp with one of the
* control flags set); uncompressed TCP (a normal IP/TCP packet but
* with the 8-bit protocol field replaced by an 8-bit connection id --
* this type of packet syncs the sender & receiver); and compressed
* TCP (described above).
*
* LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
* is logically part of the 4-bit "changes" field that follows. Top
* three bits are actual packet type. For backward compatibility
* and in the interest of conserving bits, numbers are chosen so the
* IP protocol version number (4) which normally appears in this nibble
* means "IP packet".
*/
typedef unsigned long u_long;
typedef unsigned int u_int;
typedef unsigned short u_short;
typedef unsigned char u_char;
typedef unsigned short int16;
typedef unsigned long int32;
/* IP and TCP header format */
struct ip_header {
char v_ihl; /* Version + IP header length */
#define IPVERSION 4
char tos; /* Type of service */
int16 length; /* Total length */
int16 id; /* Identification */
int16 fl_offs; /* Flags + fragment offset */
#define F_OFFSET 0x1fff /* Offset field */
#define DF 0x4000 /* Don't fragment flag */
#define MF 0x2000 /* More Fragments flag */
char ttl; /* Time to live */
char protocol; /* Protocol */
int16 checksum; /* Header checksum */
int32 source; /* Source address */
int32 dest; /* Destination address */
};
/* TCP segment header */
struct tcp_header {
int16 source; /* Source port */
int16 dest; /* Destination port */
int32 seq; /* Sequence number */
int32 ack; /* Acknowledgment number */
char offset; /* Data offset */
char flags; /* Flags, data offset */
#define DSHIFT 4 /* Data offset field */
#define DMASK 0x0f /* Mask for normalized data offset field */
#define URG 0x20 /* URGent flag */
#define ACK 0x10 /* ACKnowledgment flag */
#define PSH 0x08 /* PuSH flag */
#define RST 0x04 /* ReSeT flag */
#define SYN 0x02 /* SYNchronize flag */
#define FIN 0x01 /* FINal flag */
int16 wnd; /* Receiver flow control window */
int16 checksum; /* Header + data checksum */
int16 up; /* Urgent pointer */
};
/* IP protocol field values */
#define TCP_PTCL 6 /* Transmission Control Protocol */
#define lonibble(x) ((x) & 0x0F)
struct mbuf {
u_char *m_off; /* pointer to start of data */
int m_len; /* length of data */
};
#define mtod(m, t) ((t)(m->m_off))
/* Appendix A.1 Definitions and State Data */
#define MAX_STATES 16 /* must be >2 and <255 */
#define MAX_HDR 128 /* max TCP+IP hdr length (by protocol def) */
/* packet types */
#define TYPE_IP 0x40
#define TYPE_UNCOMPRESSED_TCP 0x70
#define TYPE_COMPRESSED_TCP 0x80
#define TYPE_ERROR 0x00 /* this is not a type that ever appears on
* the wire. The receive framer uses it to
* tell the decompressor there was a packet
* transmission error. */
/*
* Bits in the first octet of the compressed packet
*/
/* flag bits for what changed in a packet */
#define NEW_C 0x40 /* Connection id */
#define NEW_I 0x20 /* IP ID field (change != 1) */
#define TCP_PUSH_BIT 0x10 /* TCP PUSH bit */
#define NEW_S 0x08 /* Sequence number */
#define NEW_A 0x04 /* Acknowledgement */
#define NEW_W 0x02 /* Window size */
#define NEW_U 0x01 /* Urgent pointer */
/* reserved, special-case values of above */
#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */
#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */
#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)
/*
* "state" data for each active tcp conversation on the wire. This is
* basically a copy of the entire TCP/IP header from the last packet together
* with a small identifier the transmit & receive ends of the line use to
* locate the saved header.
*/
struct cstate {
struct cstate *cs_next; /* next most recently used cstate (xmit only) */
u_short cs_hlen; /* size of hdr (receive only) */
u_char cs_id; /* connection # associated with this state */
u_char cs_filler;
union {
u_char csu_hdr[MAX_HDR];
int32 csu_hdr4[1];
struct ip_header csu_ip; /* ip/tcp hdr from most recent packet */
} slcs_u;
};
#define cs_ip slcs_u.csu_ip
#define cs_hdr slcs_u.csu_hdr
#define cs_hdr4 slcs_u.csu_hdr4
/*
* all the state data for one serial line (we need one of these per line).
*/
struct slcompress {
struct cstate *tstate; /* transmit connection states (array)*/
struct cstate *rstate; /* receive connection states (array)*/
u_char tslot_limit; /* highest transmit slot id (0-l)*/
u_char rslot_limit; /* highest receive slot id (0-l)*/
struct cstate *last_cs; /* most recently used tstate */
u_char last_recv; /* last received connection id */
u_char last_xmit; /* last sent connection id */
u_char flags;
u_long sls_o_nontcp; /* outbound non-TCP packets */
u_long sls_o_tcp; /* outbound TCP packets */
u_long sls_o_uncompressed; /* outbound uncompressed packets */
u_long sls_o_compressed;/* outbound compressed packets */
u_long sls_o_searches; /* searches for connection state */
u_long sls_o_misses; /* times couldn't find conn. state */
u_long sls_i_ip; /* inbound non-TCP packets */
u_long sls_i_uncompressed; /* inbound uncompressed packets */
u_long sls_i_compressed;/* inbound compressed packets */
u_long sls_i_error; /* inbound error packets */
u_long sls_i_tossed; /* inbound packets tossed because of error */
signed char on; /* ==SL_ON: on, >0: trycount, ==0: off */
};
/* last_xmit/last_recv initial value */
#define NO_CID 255
/* flag values */
#define SLF_TOSS 1 /* tossing rcvd frames because of input err */
#define SLF_ALLOWED 2 /* allow receiving compression */
#define SLF_ON 4 /* use compression */
/* optional trycount feature */
#define TRYCOUNT 3 /* try 3 TCP_UNCOMPRESSED packets */
#define SL_ON -1 /* use compression */
/*
* The following macros are used to encode and decode numbers. They all
* assume that 'cp' points to a buffer where the next byte encoded (decoded)
* is to be stored (retrieved). Since the decode routines do arithmetic,
* they have to convert from and to network byte order.
*/
/*
* ENCODE encodes a number that is known to be non-zero. ENCODEZ checks for
* zero (zero has to be encoded in the long, 3 byte form).
*/
#define ENCODE(n) { \
if ((u_short)(n) >= 256) { \
*cp++ = 0; \
cp[1] = (n); \
cp[0] = (n) >> 8; \
cp += 2; \
} else { \
*cp++ = (n); \
} \
}
#define ENCODEZ(n) { \
if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
*cp++ = 0; \
cp[1] = (n); \
cp[0] = (n) >> 8; \
cp += 2; \
} else { \
*cp++ = (n); \
} \
}
/*
* DECODEL takes the compressed change at byte cp and adds it to the
* current value of packet field 'f' (which must be a 4-byte (long) integer
* in the current network byte order). DECODES does the same for a 2-byte (short)
* field. DECODEU takes the change at cp and stuffs it into the (short) field f.
* 'cp' is updated to point to the next field in the compressed header.
*/
#define DECODEL(f) { \
if (*cp == 0) { \
(f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \
cp += 3; \
} else { \
(f) = htonl(ntohl(f) + (u_long)*cp++); \
} \
}
#define DECODES(f) { \
if (*cp == 0) { \
(f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \
cp += 3; \
} else { \
(f) = htons(ntohs(f) + (u_short)*cp++); \
} \
}
#define DECODEU(f) { \
if (*cp == 0) { \
(f) = htons(((cp[1] << 8) | cp[2])); \
cp += 3; \
} else { \
(f) = htons((u_short)*cp++); \
} \
}
#define BCOPY(s, d, l) memcpy(d, s, l)
#define BCMP(s, d, l) memcmp(d, s, l)
#define htons(s) (s) /* on big-endian machines, that is */
#define ntohs(s) (s)
#define htonl(l) (l)
#define ntohl(l) (l)
/* Sana2 special stats values */
#define S2SS_CSLIP_O_NONTCP ((S2WireType_CSLIP << 16) | 1)
#define S2SS_CSLIP_O_TCP ((S2WireType_CSLIP << 16) | 2)
#define S2SS_CSLIP_O_UNCOMPRESSED ((S2WireType_CSLIP << 16) | 3)
#define S2SS_CSLIP_O_COMPRESSED ((S2WireType_CSLIP << 16) | 4)
#define S2SS_CSLIP_O_SEARCHES ((S2WireType_CSLIP << 16) | 5)
#define S2SS_CSLIP_O_MISSES ((S2WireType_CSLIP << 16) | 6)
#define S2SS_CSLIP_I_IP ((S2WireType_CSLIP << 16) | 17)
#define S2SS_CSLIP_I_UNCOMPRESSED ((S2WireType_CSLIP << 16) | 18)
#define S2SS_CSLIP_I_COMPRESSED ((S2WireType_CSLIP << 16) | 19)
#define S2SS_CSLIP_I_ERROR ((S2WireType_CSLIP << 16) | 20)
#define S2SS_CSLIP_I_TOSSED ((S2WireType_CSLIP << 16) | 21)
/* Prototypes for functions defined in cslip.c */
u_char sl_compress_tcp(struct mbuf *m, struct slcompress *comp);
void sl_xmit_error(struct slcompress *comp);
struct mbuf *sl_uncompress_tcp(struct mbuf *m, u_int type, struct slcompress *comp);
void sl_compress_init(struct slcompress *comp, int, int);
void sl_compress_deinit(struct slcompress *comp);